package util;

import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.CRC32;

/**
 * 类描述：   字符串操作方法
 *
 * @author yaojianfeng
 */
public class StringUtil {
    /**
     * 将null或者""转换为 "0"
     *
     * @param str 形参
     * @return String
     */
    public static String nullToZero(Object str) {
        if (str == null || "".equals(nullToString(str))) {
            return "0";
        } else {
            try {
                return str.toString().trim();
            } catch (Exception e) {
                return "0";
            }
        }
    }

    /**
     * 将null值转换为"";
     *
     * @param str 参数可以不是字符串
     * @return 字符串
     */
    public static String nullToString(Object str) {
        if (str == null) {
            return "";
        } else {
            try {
                return str.toString().trim();
            } catch (Exception e) {
                return "";
            }
        }
    }

    /**
     * 空字符串转化为 其它值
     *
     * @param object     有可能为空的参数
     * @param otherValue 将空值转化为默认值
     * @return 字符串
     */
    public static String nullToOtherString(Object object, String otherValue) {
        if (object == null) {
            return otherValue;
        } else {
            try {
                return object.toString().trim();
            } catch (Exception e) {
                return otherValue;
            }
        }
    }

    /**
     * stringToAscii asciiToString 中文转成Ascii使用时再转回string 解决中文传递乱码问题
     *
     * @param value 形参
     * @return String
     */

    public static String stringToAscii(String value) {
        StringBuffer sbu = new StringBuffer();
        if (null != value && !value.equals("")) {
            char[] chars = value.toCharArray();
            for (int i = 0; i < chars.length; i++) {
                if (i != chars.length - 1) {
                    sbu.append((int) chars[i]).append(",");
                } else {
                    sbu.append((int) chars[i]);
                }
            }
        }
        return sbu.toString();
    }

    /**
     * 全角转半角　新方法 可以对字母进行处理
     *
     * @param qjStr 全角参数
     * @return 半角字符串
     */
    public static String QJ2BJ(String qjStr) {
        qjStr = StringUtil.nullToString(qjStr);
        StringBuffer outStrBuf = new StringBuffer("");
        try {
            String Tstr = "";
            byte[] b = null;
            for (int i = 0; i < qjStr.length(); i++) {
                Tstr = qjStr.substring(i, i + 1);
                // 全角空格转换成半角空格
                if (Tstr.equals("　")) {
                    outStrBuf.append(" ");
                    continue;
                }
                b = Tstr.getBytes("unicode");
                // 得到 unicode 字节数据
                if (b[2] == -1) {
                    // 表示全角？
                    b[3] = (byte) (b[3] + 32);
                    b[2] = 0;
                    outStrBuf.append(new String(b, "unicode"));
                } else {
                    outStrBuf.append(Tstr);
                }
            }
        } catch (Exception e) {
            System.out.println("全角转半角失败,返回全角数据");
        }
        return StringUtil.nullToString(outStrBuf.toString())
                .replaceAll(" ", "").replaceAll("　", "");
    }

    /**
     * 去掉字符串后面的零
     *
     * @param string 参数
     * @return
     */
    public static String cutLastZero(String string) {
        String testStr = StringUtil.nullToString(string);
        if ("".equals(string)) {
            return "";
        }
        String lastValue = testStr.substring(testStr.length() - 1, testStr.length());
        if ("0".equals(lastValue)) {
            testStr = testStr.substring(0, testStr.length() - 1);
            //递归调用
            testStr = cutLastZero(testStr);
        }
        return testStr;
    }

    /**
     * 去掉字符串前面的零
     * @param string 字符串
     * @return 字符串
     */
    public static String cutHeadZero(String string) {
        String testStr = StringUtil.nullToString(string);
        if (string.equals("")) {
            return "";
        }
        String firstValue = testStr.substring(0, 1);
        if ("0".equals(firstValue)) {
            testStr = testStr.substring(1);
            //递归调用
            testStr = cutHeadZero(testStr);
        }
        return testStr;
    }

    /**
     * 过滤input框
     *
     * @param tmpStr 参数
     * @return
     */
    public static String filterHtml(String tmpStr) {
        //正则匹配
        Pattern pattern = Pattern
                .compile("<INPUT[^>]* value=?([^ >]*)?( [^>]*)?>");
        Matcher matcher = pattern.matcher(tmpStr);
        String string = matcher.replaceAll("<u>$1</u>");

        return string;
    }

    /**
     * 用于格式化十进制数字类型的字符串。new DecimalFormat("00.000")
     * @param value 十进制数字字符串
     * @param format 格式化模板
     * @return 格式化后的十进制数字字符串
     */
    public static String formatStrValue(String value, String format) {
        String back = "";
        try {
            DecimalFormat df = new DecimalFormat(format);
            back = df.format(Double.valueOf(value));
        } catch (Exception e) {
            e.printStackTrace();
        }

        return back;
    }

    /**
     * 字符串非空校验 null和""均视为空值
     * @param str 字符串
     * @return 布尔值 true字符串有值    false字符串为""或者null
     */
    public static boolean isNotEmpty(String str) {
        boolean bool = false;
        if (str != null && !str.trim().isEmpty()) {
            bool = true;
        }
        return bool;
    }


    /**
     * 获取uuid 可用于一般主键生成策略
     * @return
     */
    public static String getUUID() {
        return UUID.randomUUID().toString().replace("-", "");
    }

    /**
     * 将list数据转换为xml数据,与map2xml一起将数据转换为xml字符串
     *
     * @param mapList 集合中存储map数据
     * @return
     */
    public static String mapList2Xml(List<Map> mapList) {
        StringBuilder sb = new StringBuilder();
        sb.append("<list>");
        for (Map map : mapList) {
            sb.append(map2Xml(map));
        }
        sb.append("</list>");
        return sb.toString();
    }

    /**
     * 将map数据转换为xml数据,与mapList2Xml一起将数据转换为xml字符串
     *
     * @param map key-value数据源
     * @return
     */
    public static String map2Xml(Map map) {
        StringBuffer sb = new StringBuffer();
        Set set = map.keySet();
        String key = null;
        Iterator<String> it = set.iterator();
        sb.append("<map>");
        while (it.hasNext()) {
            key = it.next();
            sb.append("<key>" + key + "</key>");
            if (map.get(key) instanceof String) {
                sb.append("<value>" + map.get(key) + "</value>");
            } else if (map.get(key) instanceof Map) {
                sb.append("<value>" + map2Xml((Map) map.get(key)) + "</value>");
            } else if (map.get(key) instanceof List) {
                sb.append("<value>" + mapList2Xml((List) map.get(key)) + "</value>");
            }
        }
        sb.append("</map>");
        return sb.toString();
    }

    /**
     * 判断当前操作系统是不是window
     * @return boolean
     */
    public static boolean isWindows() {
        boolean flag = false;
        if (System.getProperties().getProperty("os.name").toUpperCase().indexOf("WINDOWS") != -1) {
            flag = true;
        }
        return flag;
    }

    /**
     * 得到crc的压缩码
     * @param str 要压缩的字符串
     * @return 压缩完后的字符串
     */
    public static String getCrc32(String str) {
        CRC32 crc32 = new CRC32();
        crc32.update(str.getBytes());
        return "K" + crc32.getValue();
    }

    /**
     * 通过正则表达式匹配字符串
     * @param source 数据源
     * @param reg 正则表达式
     * @return
     */
    public static String matchString(String source, String reg) {
        if (source == null || reg == null) {
            return null;
        }
        Matcher m = Pattern.compile(reg).matcher(source);
        if (m.find()) {
            return m.group();
        }
        return null;
    }

    /**
     * 对字符串进行扩展处理，是字符串长度固定，主要在加密使用，保证产生密文长度固定
     *
     * @param str 加密参数
     * @param len 密文长度
     * @param c 字符
     * @return 密文
     */
    public static String getFixedLenString(String str, int len, char c) {
        if (str == null || str.length() == 0) {
            str = "";
        }
        if (str.length() == len) {
            return str;
        }
        if (str.length() > len) {
            return str.substring(0, len);
        }
        StringBuilder sb = new StringBuilder(str);
        while (sb.length() < len) {
            sb.append(c);
        }
        return sb.toString();
    }


    /**
     * 得到指定位数随机码
     *
     * @param charCount 位数
     * @return 随机码
     */
    public static String getRandNum(int charCount) {
        String charValue = "";
        for (int i = 0; i < charCount; i++) {
            char c = (char) (randomInt(0, 10) + '0');
            charValue += String.valueOf(c);
        }
        return charValue;
    }

    /**
     * 得到一个位于起止间的数字随机码
     *
     * @param from 起始
     * @param to 终止
     * @return 整数
     */
    public static int randomInt(int from, int to) {
        Random r = new Random();
        return from + r.nextInt(to - from);
    }

    /**
     * 获取一定长度的随机字符串
     *
     * @param length 指定字符串长度
     * @return 一定长度的字符串
     */
    public static String getRandomStringByLength(int length) {
        String base = "abcdefghijklmnopqrstuvwxyz0123456789";
        Random random = new Random();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < length; i++) {
            int number = random.nextInt(base.length());
            sb.append(base.charAt(number));
        }
        return sb.toString();
    }


    public static String[] chars = new String[]{"a", "b", "c", "d", "e", "f",
            "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s",
            "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5",
            "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I",
            "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V",
            "W", "X", "Y", "Z"};

    /**
     * 获取8位随机码
     *
     * @return
     */
    public static String getEightUuid() {
        StringBuilder shortBuffer = new StringBuilder();
        String uuid = UUID.randomUUID().toString().replace("-", "");
        for (int i = 0; i < 8; i++) {
            String str = uuid.substring(i * 4, i * 4 + 4);
            int x = Integer.parseInt(str, 16);
            shortBuffer.append(chars[x % 0x3E]);
        }
        return shortBuffer.toString();

    }

    /**
     * 测试是否为正常的手机号码 大陆号码 非港澳台号码
     * @param phone 电话号码
     * @return 布尔值
     */
    public static boolean isPhone(String phone) {
        return phone.matches("^((13[0-9])|(15[^4])|(18[0,2,3,5-9])|(17[0-8])|(147))\\d{8}$");
    }


    /**
     * @param difference 与今天的日期差
     * @param separator  分割符
     * @return
     */
    public static String getDateString(int difference, String separator) {
        String format = "yyyy" + separator + "MM" + separator + "dd";
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        GregorianCalendar gc = new GregorianCalendar();
        gc.setTime(new Date());
        gc.add(5, difference);
        return sdf.format(gc.getTime());
    }

    /**
     * @param difference 与今天的日期差
     * @return 默认返回格式yyyy-MM-dd
     */
    public static String getDateString(int difference) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        GregorianCalendar gc = new GregorianCalendar();
        gc.setTime(new Date());
        gc.add(5, difference);
        return sdf.format(gc.getTime());
    }

    /**
     * @param format     日期格式
     * @param difference 与今天的日期差
     * @return
     */
    public static String getDateString(String format, int difference) {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        GregorianCalendar gc = new GregorianCalendar();
        gc.setTime(new Date());
        gc.add(5, difference);
        return sdf.format(gc.getTime());
    }


}
